package com.impress.commons.exception;

import java.lang.reflect.Field;
import java.util.LinkedList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author Wangyi
 * @since 2016年6月23日
 */
public class ErrorCodeEntry {

	public static final Logger log = LoggerFactory.getLogger(ErrorCodeEntry.class);

	private final String code;
	private final Integer httpStatusHint;
	private final String message;

	/**
	 * @param code
	 * @param httpStatusHint
	 * @param message
	 */
	public ErrorCodeEntry(String code, Integer httpStatusHint, String message) {
		super();
		this.code = code;
		this.httpStatusHint = httpStatusHint;
		this.message = message;
	}

	/**
	 * @param code
	 * @param message
	 */
	public ErrorCodeEntry(String code, String message) {
		super();
		this.code = code;
		this.message = message;
		this.httpStatusHint = null;
	}

	public static final List<ErrorCodeEntry> findStaticErrorCodes(Class<?> clazz) {
		List<ErrorCodeEntry> list = new LinkedList<ErrorCodeEntry>();
		Field[] declaredFields = clazz.getDeclaredFields();
		for (Field field : declaredFields) {
			if (java.lang.reflect.Modifier.isStatic(field.getModifiers())) {
				if (ErrorCodeEntry.class.isAssignableFrom(field.getType())) {
					try {
						list.add((ErrorCodeEntry) field.get(clazz));
					} catch (IllegalAccessException e) {
						log.error("", e);
					}
				}
			}
		}
		return list;
	}

	/**
	 * @return the message
	 */
	public String getMessage() {
		return message;
	}

	/**
	 * @return the code
	 */
	public String getCode() {
		return code;
	}

	/**
	 * @return the httpStatusHint
	 */
	public Integer getHttpStatusHint() {
		return httpStatusHint;
	}

	/**
	 * born有产生的意思，此方法仅方便new {@link RawErrorCodeException},调用端需要显示使用{@code throw}抛出异常
	 * 
	 * @return
	 */
	public final RawErrorCodeException bornException() {
		return new RawErrorCodeException(this);
	}

	/**
	 * born有产生的意思，此方法仅方便new {@link RawErrorCodeException},调用端需要显示使用{@code throw}抛出异常
	 * 
	 * @param cause
	 * @return
	 */
	public final RawErrorCodeException bornException(Throwable cause) {
		return new RawErrorCodeException(this, cause);
	}

	@Override
	public String toString() {
		StringBuilder builder = new StringBuilder();
		builder.append("{code:");
		builder.append(code);
		builder.append(", httpStatusHint:");
		builder.append(httpStatusHint);
		builder.append(", message:");
		builder.append(message);
		builder.append("}");
		return builder.toString();
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((code == null) ? 0 : code.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (getClass() != obj.getClass()) {
			return false;
		}
		ErrorCodeEntry other = (ErrorCodeEntry) obj;
		if (code == null) {
			if (other.code != null) {
				return false;
			}
		}
		else if (!code.equals(other.code)) {
			return false;
		}
		return true;
	}

}
